package pl.edu.pw.mini.java2.Communicator.Client;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 * 
 * @author Dymitr Załunin, Kamil Łysik.
 * Klasa odpowiadająca za tworzenie i obsługę GUI dla okna czatu po stronie Klienta.
 * Implementuje interfejs {@link ChatListener} .
 */
public class ChatWindow extends JDialog implements ChatListener {
	private static final long serialVersionUID = -744626908699714671L;

	private JTextArea chatLog = new JTextArea();
	private JTextField inputLine = new JTextField();
	private JButton sendButton = new JButton("Send");
	private JButton disconnectButton = new JButton("Disconnect");
	private JScrollPane areaScrollPane;
	private Client client;
	private String myName;
	private String pairName;
	private MicrophoneCollecter recorder;
	
	/**
	 * Zwraca imię klienta z którym trwa rozmowa.
	 * @return String
	 */
	public String getPairName() {
		return pairName;
	}

	/**
	 * Ustawia imię klienta dla czatu.
	 * @param pairName String Imie.
	 */
	public void setPairName(String pairName) {
		this.pairName = pairName;
		chatLog.append("Start chat with "+pairName+"\n");
	}

	/**
	 * Przywiazuję obiekt typu Client do GUI okna czatu.
	 * @param client obiekt typu Client.
	 */
	public void setClient(Client client) {
		if (recorder != null) {
			recorder.stopRecording();
			recorder = null;
		}
		this.client = client;
		myName = client.getLoginInfo().getLogin();
		setTitle(myName);
		if (client != null) {
			recorder = new MicrophoneCollecter(client);
			recorder.start();
		}
	}

	/**
	 * Konstruktor bezparametrowy, tworzący nowe onko czatu.
	 */
	public ChatWindow() {

		initUI();
		sendButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				sendMessage();
			}
		});
		inputLine.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				sendMessage();
			}
		});
		disconnectButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				chatReject();
			}
		});
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				chatReject();
			}
		});
	}

	/**
	 * Metoda do obsługi przychodzącej wiadomosci tekstowej.
	 * @param m Text przychodzącej wiadomości.
	 */
	@Override
	public void readTextMessage(String m) {
		getMessage(m);
	}
	
	/**
	 * Metoda do obsługi przerwania czatu.
	 */
	@Override
	public void chatReject() {
		if (recorder != null)
			recorder.stopRecording();
		disconnect();
		setVisible(false);
	}

	private synchronized void getMessage(String m) {
		chatLog.append(pairName + ": " + m + "\n");
	}

	private synchronized void sendMessage() {
		if (inputLine.getText().length() == 0)
			return;
		if (client == null)
			return;
		client.sendChatTextMessage(inputLine.getText());
		chatLog.append(myName + ": " + inputLine.getText() + "\n");
		inputLine.setText("");
	}

	private void disconnect() {
		try {
			client.sendChatRejectRequest();
		} catch (Exception e) {
		}
	}

	private void initUI() {
		setLayout(new BorderLayout());
		chatLog.setLineWrap(true);
		chatLog.setWrapStyleWord(true);
		areaScrollPane = new JScrollPane(chatLog);
		areaScrollPane
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		add(areaScrollPane, BorderLayout.CENTER);
		JPanel line = new JPanel();
		line.setLayout(new BorderLayout());
		line.add(inputLine, BorderLayout.CENTER);
		line.add(sendButton, BorderLayout.EAST);
		add(line, BorderLayout.SOUTH);
		Box verticalBox = Box.createVerticalBox();
		verticalBox.add(Box.createVerticalGlue());
		verticalBox.add(disconnectButton);
		verticalBox.add(Box.createVerticalGlue());
		add(verticalBox, BorderLayout.EAST);
		chatLog.setEditable(false);
		setSize(500, 300);
	}
}